/***************************************************************************
 *cr
 *cr            (C) Copyright 1995-2019 The Board of Trustees of the
 *cr                        University of Illinois
 *cr                         All Rights Reserved
 *cr
 ***************************************************************************/

/***************************************************************************
 * RCS INFORMATION:
 *
 *      $RCSfile: DisplayFltkMenu.C,v $
 *      $Author: johns $        $Locker:  $             $State: Exp $
 *      $Revision: 1.26 $       $Date: 2019/01/17 21:20:59 $
 *
 ***************************************************************************
 * DESCRIPTION:
 *   generated by Fast Light User Interface Designer (fluid) version 1.0011
 ***************************************************************************/

#include "DisplayFltkMenu.h"
#include "Command.h"
#include "VMDApp.h"
#include "DisplayDevice.h"
#include "FL/forms.H"

DisplayFltkMenu::DisplayFltkMenu(VMDApp *anApp)
: VMDFltkMenu("display", "Display Settings", anApp) {
  make_window();
  update_settings();
  command_wanted(Command::DISP_EYESEP);
  command_wanted(Command::DISP_FOCALLEN);
  command_wanted(Command::DISP_CLIP);
  command_wanted(Command::DISP_SCRHEIGHT);
  command_wanted(Command::DISP_SCRDIST);
  command_wanted(Command::DISP_CUEMODE);
  command_wanted(Command::DISP_CUESTART);
  command_wanted(Command::DISP_CUEEND);
  command_wanted(Command::DISP_CUEDENSITY);
  command_wanted(Command::DISP_AO);
  command_wanted(Command::DISP_AO_AMBIENT);
  command_wanted(Command::DISP_AO_DIRECT);
  command_wanted(Command::DISP_DOF);
  command_wanted(Command::DISP_DOF_FNUMBER);
  command_wanted(Command::DISP_DOF_FOCALDIST);
}


static void nearclip_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_nearclip(value, 0);
}
static void farclip_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_farclip(value, 0);
}
static void eyesep_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_eyesep(value);
}
static void focal_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_focallen(value);
}
static void screenh_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_screen_height(value);
}
static void screend_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_screen_distance(value);
}


static void cuemode_cb(Fl_Widget *w, void *v) {
  const char *mode = ((Fl_Choice *)w)->text();
  VMDApp *app = (VMDApp *)v;
  app->depthcue_set_mode(mode);
}
static void cuestart_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->depthcue_set_start(value);
}
static void cueend_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->depthcue_set_end(value);
}
static void cuedensity_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->depthcue_set_density(value);
}


static void shadowmode_cb(Fl_Widget *w, void *v) {
  const char *mode = ((Fl_Choice *)w)->text();
  VMDApp *app = (VMDApp *)v;
  if (!strcmp(mode, "On")) {
    app->display_set_shadows(1);
  } else {
    app->display_set_shadows(0);
  }
}


static void aomode_cb(Fl_Widget *w, void *v) {
  const char *mode = ((Fl_Choice *)w)->text();
  VMDApp *app = (VMDApp *)v;
  if (!strcmp(mode, "On")) {
    app->display_set_ao(1);
  } else {
    app->display_set_ao(0);
  }
}
static void aoambient_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_ao_ambient(value);
}
static void aodirect_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_ao_direct(value);
}


static void dofmode_cb(Fl_Widget *w, void *v) {
  const char *mode = ((Fl_Choice *)w)->text();
  VMDApp *app = (VMDApp *)v;
  if (!strcmp(mode, "On")) {
    app->display_set_dof(1);
  } else {
    app->display_set_dof(0);
  }
}
static void doffnumber_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_dof_fnumber(value);
}
static void doffocaldist_cb(Fl_Widget *w, void *v) {
  float value = (float)((Fl_Valuator *)w)->value();
  VMDApp *app = (VMDApp *)v;
  app->display_set_dof_focal_dist(value);
}


void DisplayFltkMenu::make_window() {
  size(235, 530);
  { 
    { Fl_Counter* o = nearclip = new Fl_Counter(105, 25, 110, 25, "Near Clip");
      o->align(FL_ALIGN_LEFT);
      o->range(0.01, 1000.0);
      o->step(0.05);
      o->lstep(0.5);
      o->precision(2);
      o->callback(nearclip_cb, app);
      VMDFLTKTOOLTIP(o, "Set near clipping plane (OpenGL display only)")
    }
    { Fl_Counter* o = farclip = new Fl_Counter(105, 50, 110, 25, "Far Clip");
      o->align(FL_ALIGN_LEFT);
      o->range(0.01, 1000.0);
      o->step(0.05);
      o->lstep(0.5);
      o->precision(2);
      o->callback(farclip_cb, app);
      VMDFLTKTOOLTIP(o, "Set far clipping plane (OpenGL display only)")
    }
    { Fl_Counter* o = eyesep = new Fl_Counter(105, 75, 110, 25, "Eye Sep");
      o->align(FL_ALIGN_LEFT);
      o->range(0.0, 100.0);
      o->step(0.01);
      o->lstep(0.1);
      o->precision(2);
      o->callback(eyesep_cb, app);
      VMDFLTKTOOLTIP(o, "Set stereo eye separation")
    }
    { Fl_Counter* o = focal = new Fl_Counter(105, 100, 110, 25, "Focal Length");
      o->align(FL_ALIGN_LEFT);
      o->range(0.01, 1000.0);
      o->step(0.05);
      o->lstep(0.5);
      o->precision(2);
      o->callback(focal_cb, app);
      VMDFLTKTOOLTIP(o, "Set stereo focal point")
    }
    { Fl_Counter* o = screenh = new Fl_Counter(105, 135, 110, 25, "Screen Hgt");
      o->align(FL_ALIGN_LEFT);
      o->range(0.0, 100000.0);
      o->step(0.1);
      o->lstep(1.0);
      o->precision(1);
      o->callback(screenh_cb, app);
      VMDFLTKTOOLTIP(o, "Set viewing frustum height")
    }
    { Fl_Counter* o = screend = new Fl_Counter(105, 160, 110, 25, "Screen Dist");
      o->align(FL_ALIGN_LEFT);
      o->range(-100000.0, 100000.0);
      o->step(0.1);
      o->lstep(1.0);
      o->precision(1);
      o->callback(screend_cb, app);
      VMDFLTKTOOLTIP(o, "Set viewing frustum distance")
    }

    { Fl_Choice* o = cuemode = new Fl_Choice(105, 195, 110, 25, "Cue Mode");
      o->color(VMDMENU_CHOOSER_BG);
      o->selection_color(VMDMENU_CHOOSER_SEL);
      o->box(FL_THIN_UP_BOX);
      o->align(FL_ALIGN_LEFT);
      o->callback(cuemode_cb, app);
      VMDFLTKTOOLTIP(o, "Set depth cueing mode")
      for (int m=0; m<app->display->num_cue_modes(); m++)
        cuemode->add(app->display->cue_mode_name(m));
    }
    { Fl_Counter* o = cuestart = new Fl_Counter(105, 220, 110, 25, "Cue Start");
      o->align(FL_ALIGN_LEFT);
      o->range(0.001, 1000.0);
      o->step(0.05);
      o->lstep(0.25);
      o->precision(2);
      o->callback(cuestart_cb, app);
      VMDFLTKTOOLTIP(o, "Set linear depth cueing starting distance")
    }
    { Fl_Counter* o = cueend = new Fl_Counter(105, 245, 110, 25, "Cue End");
      o->align(FL_ALIGN_LEFT);
      o->range(0.001, 1000.0);
      o->step(0.05);
      o->lstep(0.25);
      o->precision(2);
      o->callback(cueend_cb, app);
      VMDFLTKTOOLTIP(o, "Set linear depth cueing end distance")
    }
    { Fl_Counter* o = cuedensity = new Fl_Counter(105, 270, 110, 25, "Cue Density");
      o->align(FL_ALIGN_LEFT);
      o->range(0.001, 1000.0);
      o->step(0.05);
      o->lstep(0.1);
      o->precision(2);
      o->callback(cuedensity_cb, app);
      VMDFLTKTOOLTIP(o, "Set exponential depth cueing density")
    }

    new Fl_Box(35, 305, 170, 25, "Ray Tracing Options");
    { Fl_Choice* o = shadowmode = new Fl_Choice(105, 330, 110, 25, "Shadows");
      o->color(VMDMENU_CHOOSER_BG);
      o->selection_color(VMDMENU_CHOOSER_SEL);
      o->box(FL_THIN_UP_BOX);
      o->align(FL_ALIGN_LEFT);
      o->callback(shadowmode_cb, app);
      VMDFLTKTOOLTIP(o, "Enable shadows in external renderers")
      shadowmode->add("Off");
      shadowmode->add("On");
    }
    { Fl_Choice* o = aomode = new Fl_Choice(105, 355, 110, 25, "Amb. Occl.");
      o->color(VMDMENU_CHOOSER_BG);
      o->selection_color(VMDMENU_CHOOSER_SEL);
      o->box(FL_THIN_UP_BOX);
      o->align(FL_ALIGN_LEFT);
      o->callback(aomode_cb, app);
      VMDFLTKTOOLTIP(o, "Enable ambient occlusion lighting in external renderers")
      aomode->add("Off");
      aomode->add("On");
    }
    { Fl_Counter* o = aoambient = new Fl_Counter(105, 380, 110, 25, "AO Ambient");
      o->align(FL_ALIGN_LEFT);
      o->range(0.0, 1.0);
      o->step(0.01);
      o->lstep(0.10);
      o->precision(2);
      o->callback(aoambient_cb, app);
      VMDFLTKTOOLTIP(o, "Ambient occlusion lighting coefficient")
    }
    { Fl_Counter* o = aodirect = new Fl_Counter(105, 405, 110, 25, "AO Direct");
      o->align(FL_ALIGN_LEFT);
      o->range(0.0, 1.0);
      o->step(0.01);
      o->lstep(0.10);
      o->precision(2);
      o->callback(aodirect_cb, app);
      VMDFLTKTOOLTIP(o, "Direct lighting rescaling coefficient")
    }


    { Fl_Choice* o = dofmode = new Fl_Choice(105, 430, 110, 25, "DoF");
      o->color(VMDMENU_CHOOSER_BG);
      o->selection_color(VMDMENU_CHOOSER_SEL);
      o->box(FL_THIN_UP_BOX);
      o->align(FL_ALIGN_LEFT);
      o->callback(dofmode_cb, app);
      VMDFLTKTOOLTIP(o, "Enable depth of field focal blur in external renderers")
      dofmode->add("Off");
      dofmode->add("On");
    }
    { Fl_Counter* o = doffnumber = new Fl_Counter(105, 455, 110, 25, "DoF f/stop");
      o->align(FL_ALIGN_LEFT);
      o->range(1.0, 500.0);
      o->step(0.05);
      o->lstep(1.0);
      o->precision(2);
      o->callback(doffnumber_cb, app);
      VMDFLTKTOOLTIP(o, "Depth of field focal blur aperture")
    }
    { Fl_Counter* o = doffocaldist = new Fl_Counter(105, 480, 110, 25, "DoF Foc. Dist");
      o->align(FL_ALIGN_LEFT);
      o->range(0.01, 100.0);
      o->step(0.01);
      o->lstep(0.2);
      o->precision(2);
      o->callback(doffocaldist_cb, app);
      VMDFLTKTOOLTIP(o, "Depth of field focal plane distance")
    }


    Fl_Box *box1 = new Fl_Box(10, 10, 215, 120);
    box1->box(FL_ENGRAVED_FRAME);
    Fl_Box *box2 = new Fl_Box(10, 130, 215, 65);
    box2->box(FL_ENGRAVED_FRAME);
    Fl_Box *box3 = new Fl_Box(10, 190, 215, 110);
    box3->box(FL_ENGRAVED_FRAME);
    Fl_Box *box4 = new Fl_Box(10, 300, 215, 210);
    box4->box(FL_ENGRAVED_FRAME);
    end();
    end();
  }
}

int DisplayFltkMenu::act_on_command(int, Command *) {
  update_settings();
  return 0;
}

void DisplayFltkMenu::update_settings() {
  nearclip->value(app->display->near_clip());
  farclip->value(app->display->far_clip());
  eyesep->value(app->display->eyesep());
  focal->value(app->display->eye_dist());
  screenh->value(app->display->screen_height());
  screend->value(app->display->distance_to_screen());
  const char *curmode = app->display->get_cue_mode();
  for (int m=0; m<cuemode->size(); m++) {
    if (!strcmp(curmode, cuemode->text(m))) {
      cuemode->value(m);
      if (m==0) { // Linear
        cuestart->activate();
        cueend->activate();
        cuedensity->deactivate();
      } else {  // Exp or Exp2
        cuestart->deactivate();
        cueend->deactivate();
        cuedensity->activate();
      }
      break;
    }
  }
  cuestart->value(app->display->get_cue_start());
  cueend->value(app->display->get_cue_end());
  cuedensity->value(app->display->get_cue_density());

  shadowmode->value(app->display->shadows_enabled());

  aomode->value(app->display->ao_enabled());
  aoambient->value(app->display->get_ao_ambient());
  aodirect->value(app->display->get_ao_direct());
  if (app->display->ao_enabled()) {
    aoambient->activate();
    aodirect->activate();
  } else {
    aoambient->deactivate();
    aodirect->deactivate();
  }

  dofmode->value(app->display->dof_enabled());
  doffnumber->value(app->display->get_dof_fnumber());
  doffocaldist->value(app->display->get_dof_focal_dist());
  if (app->display->dof_enabled()) {
    doffnumber->activate();
    doffocaldist->activate();
  } else {
    doffnumber->deactivate();
    doffocaldist->deactivate();
  }

}


